<?php

declare(strict_types=1);

namespace App\Middleware;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

/**
 * 权限验证
 */
class AuthMiddleware implements MiddlewareInterface
{
    protected ContainerInterface $container;

    protected RequestInterface $request;

    protected HttpResponse $response;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response  = $response;
        $this->request   = $request;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {

        $user_info = $this->request->user_info;
        $path      = $this->request->getPathInfo(); // 获取请求的接口

        // 获取当前商户的登录信息
        $current_info = $this->getCurrentInfo($user_info['user_id']);
        // 获取当前登录商户的用户信息
        $current_user = $this->getUser($user_info['user_id']);
        if (empty($current_info) || empty($current_user)){
            return $this->response->json(
                [
                    'code' => -1003,
                    'data' => [
                        'error' => 'unregistered.',
                    ],
                ]
            );
        }

        // 判断是否拥有当前接口的权限
        if ($this->isAuth($current_user, $path)) {
            return $handler->handle($request);
        }

        // 返回没有权限
        return $this->response->json(
            [
                'code' => -4003,
                'data' => [
                    'error' => 'You do not have permission.',
                ],
            ]
        );

    }

    /**
     * 判断权限是否拥有
     * @param mixed $user_info
     * @param string $path
     * @return bool
     */
    private function isAuth(mixed $current_user, string $path): bool
    {
        // 超级管理员跳过
        if (in_array(1, $current_user['group_ids'])) {
            return true;
        }

        // 获取权限组下的权限
        $groupArr = [];
        foreach ($current_user['group_ids'] as $group_id)
        {
            $groupArr = array_merge($groupArr, $this->getAuthGroup($group_id));
        }
        if (in_array($path, $groupArr)) {
            return true;
        }

        return false;
    }

    /**
     * (商户表)通过用户ID获取所拥有的商户信息
     * @param $user_info
     * @return array|int[]
     */
    private function getCurrentInfo(int $user_id): array
    {
        return match ($user_id)
        {
            1 => [
                [
                    'id' => 1001,
                    'name' => '商户1',
                ],
                [
                    'id' => 1002,
                    'name' => '商户2',
                ],
            ],
            2 => [
                [
                    'id' => 1003,
                    'name' => '商户3',
                ],
            ],
            3 => [
                [
                    'id' => 1004,
                    'name' => '商户4',
                ],
            ],
            default => [],
        };
    }

    /**
     * （商户下用户表）当前商户下的成员（每创建一个商户自动生成总管理员的一个账号）
     * @return void
     */
    private function getUser(int $user_id): array
    {
        return match ($user_id) {
            1 => [
                'appid' => 1001, // 商户id
                'user_id' => 1, //当前商户下当前登录的用户id
                'group_ids' => [1], // 角色组，固定1为当前商户的超级管理员
                'login_name' => 'username'
            ],
            2 => [
                'appid' => 1002,
                'user_id' => 2,
                'group_ids' => [3],
                'login_name' => 'username2'
            ],
            3 => [
                'appid' => 1003,
                'user_id' => 2,
                'group_ids' => [1],
                'login_name' => 'username3'
            ],
            default => [],
        };
    }

    /**
     * (权限组表)获取权限路径
     * @param int $auth_group
     * @return array|string[]
     */
    private function getAuthGroup(int $auth_group): array
    {
        return match ($auth_group) {
            2 => ['/api/merchanInfo', '/api/orderCount'],
            3 => ['/api/orderCount', ],

            default => [],
        };
    }

}
